//=========================================================================
// Copyright (C) 2024 The C++ Component Model(COMO) Open Source Project
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
//      http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
//=========================================================================

#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <assert.h>
#include <sys/select.h>
#include <unistd.h>
#include <termios.h>
#include <errno.h>
#include <fcntl.h>
#include "voter_message.h"
#include "voter_lib.h"
#include "voter_client.h"

/**
 * Main program logic, finally :)
 */
int main(int argc, char **argv)
{
    if (argc != 3) {
        printf("Usage: %s <host> <port>\n", argv[0]);
        exit(1);
    }

    // Create a TCP connection with the server.
    int s = TCPConnect(argv[1], atoi(argv[2]), 0);
    if (-1 == s) {
        perror("Connecting to server");
        exit(1);
    }

    /**
     * Wait for the standard input or the server socket to
     * have some data.
     */
    fd_set readfds;

    bool first = true;
    char pathname[] = "como-fscp-voter.data";

    int in_fd = open(pathname, O_RDONLY);
    if (in_fd < 0) {
        printf("open error for %s\n", pathname);
    }

    while (true) {
        FD_ZERO(&readfds);
        FD_SET(s, &readfds);
        int maxfd = s > in_fd ? s : in_fd;

        int num_events = select(maxfd+1, &readfds, NULL, NULL, NULL);
        if (-1 == num_events) {
            perror("select() error");
            exit(1);
        }
        else if (0 != num_events) {
            char buf[MAX_VoterMessage_SIZE];  // Generic buffer for both code paths.

            if (FD_ISSET(s, &readfds)) {
                // Data from the server
                ssize_t nread = read(s, buf, sizeof(buf));
                if (nread <= 0) {
                    printf("Connection lost\n");
                    exit(1);
                }
                if (first) {
                    printf("Received signatrue from server:\n");
                    print_hex(buf, nread);
#ifdef ZMQ_MODE
                    ResponseZMQ(s, true);
                    printf("Responsed to server: ZMQ_MODE\n");
#else
                    ResponseZMQ(s, false);
                    printf("Responsed to server: NON_ZMQ_MODE\n");
#endif
                    first = false;
                }

            }
            else if (FD_ISSET(in_fd, &readfds)) {
                ssize_t nread;

                if (in_fd < 0) {
                    memset(buf, 't', sizeof(buf));
                    buf[sizeof(buf) - 1] = '\0';
                }
                else {
                    nread = read(in_fd, buf, sizeof(buf));
                    if (nread != sizeof(buf)) {
                        ;
                    }
                }

                char buffer[MAX_VoterMessage_SIZE];
                VoterMessage *box = BoxVoterMessage(buffer,
                            MAX_VoterMessage_SIZE,  // bufSize
                            VOTER_SYNC_CLOCK,       // type
                            0,                      // idTransaction
                            0,                      // lamportClock,
                            0,                      // data
                            buf,
                            0);
                int num = write(s, box, box->len);
                if (num != box->len) {
                    ;
                }
            }
        }
    }

    close(s);
    return 0;
}
